//
//  DBConnection.swift
//  MoYoung
//
//  Created by sylar on 16/10/21.
//  Copyright © 2016年 sylar. All rights reserved.
//

import SQLite

public protocol SQLiteManagerDelegate {
    
    func createTables(_ manager: SQLiteManager) ->[SQLiteTableiabe.Type]
    
    func didCreateTables(_ manager: SQLiteManager)
    
    
}


open class SQLiteManager: NSObject {
    
    public static let shared = SQLiteManager()
    public var connection: Connection?
    public var name: String = "db.sqlite3" {
        didSet {
            connection = try? Connection(self.path)
        }
    }
    
    public var delegate: SQLiteManagerDelegate?
    
    fileprivate var tables: [SQLiteTableiabe.Type] = []
    
    private let version = "0.0.1"
    
    private override init() {
        super.init()
        
        connection = try? Connection(self.path)
        
        makeTables()
        
    }
    
    private var path : String {
        let root = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let path = "\(root)/\(name)"
        
        print("sqlite path: \(path)")
        return path
        
    }
    
    
    @discardableResult
    public func create(_ tables:[SQLiteTableiabe.Type]) ->SQLiteManager {
        
        tables.forEach {
            self.create($0)
        }
        return self
    }
    
    @discardableResult
    public func create(_ table: SQLiteTableiabe.Type) ->SQLiteManager {
        
        do {
            try self.connection?.run(table.create)
        }
        catch {
            
        }
        
        return self
    }
    
    @discardableResult
    public func update(_ tables: [SQLiteTableiabe.Type]) ->SQLiteManager {
        
        tables.forEach {
            $0.updateColumns()
        }
        return self
    }
    
    @discardableResult
    public func delete(_ tables: [SQLiteTableiabe.Type]) ->SQLiteManager {
        
        tables.forEach {
            
            do {
                
                try $0.db.run($0.table.delete())
                
            } catch {
                
            }
            
            
        }
        return self
    }
    
    
    public func makeTables() {
        
        let tables = delegate?.createTables(self)
        guard let tables = tables else {
            delegate?.didCreateTables(self)
            return
        }
        
        self.tables = tables
        
        create(tables)
        
        update(tables)
        
        delegate?.didCreateTables(self)
        
    }
    
    public func deleteTables() {
        
        delete(self.tables)
        
    }
    
}

